package com.qigao.mall.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qigao.mall.api.AccountInfoService;
import com.qigao.mall.api.AccountSerivce;
import com.qigao.mall.api.SettleTotalService;
import com.qigao.mall.commons.dto.*;
import com.qigao.mall.commons.enums.*;
import com.qigao.mall.commons.utils.DateUtil;
import com.qigao.mall.jdbc.mapper.TbSettleDetailMapper;
import com.qigao.mall.jdbc.mapper.TbSettleTotalMapper;
import com.qigao.mall.jdbc.model.TbOrderTotal;
import com.qigao.mall.jdbc.model.TbSettleDetail;
import com.qigao.mall.jdbc.model.TbSettleTotal;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author luiz
 * @Title: com.qigao.mall.service.impl
 * @ProjectName market-parent
 * @date 2020-06-2020-06-19 14:58
 * @Description:
 */
@Service
@Slf4j
public class SettleTotalServiceImpl implements SettleTotalService {
    @Resource
    private TbSettleTotalMapper tbSettleTotalMapper;
    @Resource
    private TbSettleDetailMapper tbSettleDetailMapper;
    @Resource
    private AccountSerivce accountSerivce;
    @Resource
    DataSourceTransactionManager transactionManager;

    @Override
    public void saveBySettleDate(TbSettleTotal tbSettleTotal) {
        if(tbSettleTotal==null)return;
        TbSettleTotal tbSettleTotal1=tbSettleTotalMapper.selectBySettleDate(tbSettleTotal.getSettleDate());
        if(tbSettleTotal1==null){
            //不存在则新增
            tbSettleTotalMapper.insertSelective(tbSettleTotal);
        }else {
            //存在则累加
            tbSettleTotalMapper.addSettleTotal(tbSettleTotal);
        }
    }
    @Override
    public void saveBatch(List<TbSettleTotal> tbSettleTotals) {
        for(TbSettleTotal tbSettleTotal:tbSettleTotals){
            // todo
        }

    }

    @Override
    public int countBySettleDate(Date settleDate) {
        return tbSettleTotalMapper.countBySettleDate(settleDate);
    }

    @Override
    public void insert(TbSettleTotal tbSettleTotal) {
        tbSettleTotalMapper.insertSelective(tbSettleTotal);
    }

    @Override
    public Result<PageInfo<SettleTotalResultDto>> listPage(SettleQueryDto settleQueryDto) {
        PageHelper.startPage(settleQueryDto.getPageNum(),settleQueryDto.getPageSize());
        Page<TbSettleTotal> tbSettleTotalPage=(Page<TbSettleTotal>)tbSettleTotalMapper.selectByCond(settleQueryDto);
        return convertToDto(tbSettleTotalPage);
    }

    @Override
    public List<SettleTotalResultDto> findOrderResultByCond(SettleQueryDto settleQueryDto) {
        List<TbSettleTotal> tbSettleTotalList=(List<TbSettleTotal>)tbSettleTotalMapper.selectByCond(settleQueryDto);
        List<SettleTotalResultDto> settleTotalResultDtos=new ArrayList<>();
        for(TbSettleTotal tbSettleTotal:tbSettleTotalList){
            SettleTotalResultDto settleTotalResultDto=new SettleTotalResultDto();
            BeanUtils.copyProperties(tbSettleTotal,settleTotalResultDto);
            settleTotalResultDto.setSettleDate(DateUtil.getDateFormat(tbSettleTotal.getSettleDate()));
            int settleStatus=tbSettleTotal.getSettleStatus()==null?0:tbSettleTotal.getSettleStatus().intValue();
            settleTotalResultDto.setSettleStatusName(SettleStatusEnum.getNameByCode(settleStatus));
            settleTotalResultDto.setAuditTime(DateUtil.getDateTimeFormat(tbSettleTotal.getAuditTime()));
            settleTotalResultDto.setCreateTime(DateUtil.getDateTimeFormat(tbSettleTotal.getCreateTime()));
            settleTotalResultDto.setModiTime(DateUtil.getDateTimeFormat(tbSettleTotal.getModiTime()));
            settleTotalResultDtos.add(settleTotalResultDto);
        }
        return settleTotalResultDtos;
    }

    @Override
    public void insertBatch(List<TbSettleTotal> tbSettleTotals) {
        if(CollectionUtils.isEmpty(tbSettleTotals))return;
        tbSettleTotalMapper.insertBatch(tbSettleTotals);
    }



    @Override
    public Result settleAudit(SettleAuditDto settleAuditDto) {
        for(String orderNo:settleAuditDto.getOrderNos()){
            settleAuditDto.setOrderNo(orderNo);
            singleAudit(settleAuditDto);
        }
        return Result.newSuccess();
    }

    private Result singleAudit(SettleAuditDto settleAuditDto) {
        //状态检查
        TbSettleTotal tbSettleTotal=tbSettleTotalMapper.selectByPrimaryKey(Long.valueOf(settleAuditDto.getOrderNo()));
        if(SettleStatusEnum.SETTLE.getCode()==tbSettleTotal.getSettleStatus()){
            return Result.newSuccess(ResultCode.COND_NOT_ALLOWED);
        }
        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
        defaultTransactionDefinition.setName(TransactionTypeEnum.AUDIT_SETTLE.getCode());
        defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus transactionStatus = transactionManager.getTransaction(defaultTransactionDefinition);
        try {
            // todo 分页查询
            List<TbSettleDetail> tbSettleDetails=tbSettleDetailMapper.selectBySettleNo(tbSettleTotal.getSettleNo());
            //账户余额记录
            for(TbSettleDetail tbSettleDetail:tbSettleDetails){
                AccountAmtOperDto accountAmtOperDto=new AccountAmtOperDto();
                accountAmtOperDto.setAccoutNo(tbSettleDetail.getAccountNo());
                accountAmtOperDto.setSourceTradeType(TradeTypeEnum.SETTLE_AMT);
                accountAmtOperDto.setTradeAmt(tbSettleDetail.getActSettleAmt());
                accountAmtOperDto.setSourceOrderNo(tbSettleDetail.getSettleNo());
                accountSerivce.operAccountAmt(accountAmtOperDto);
            }
            tbSettleTotal.setSettleStatus(SettleStatusEnum.SETTLE.getCode());
            tbSettleTotal.setAuditNo(settleAuditDto.getUserNo());
            tbSettleTotal.setAuditMemo(settleAuditDto.getAuditDesc());
            tbSettleTotal.setAuditTime(new Date());
            tbSettleTotal.setModiTime(new Date());
            tbSettleTotalMapper.updateByPrimaryKeySelective(tbSettleTotal);
            transactionManager.commit(transactionStatus);
            log.info("对结算订单号:{}进行结算单审核成功!",settleAuditDto.getOrderNo());
            return Result.newSuccess();
        } catch (Exception e) {
            log.error("结算单审核发生异常,事务回滚:{}", e);
            transactionManager.rollback(transactionStatus);
            return Result.newError(ResultCode.SAVE_DB_ERROR);
        }
    }

    private Result<PageInfo<SettleTotalResultDto>> convertToDto(Page<TbSettleTotal> tbSettleTotalPage) {
        Page<SettleTotalResultDto> settleTotalResultDtoPage=new Page<SettleTotalResultDto>();
        BeanUtils.copyProperties(tbSettleTotalPage,settleTotalResultDtoPage);
        if(tbSettleTotalPage.getResult()!=null){
            for(TbSettleTotal tbSettleTotal:tbSettleTotalPage.getResult()){
                SettleTotalResultDto settleTotalResultDto=new SettleTotalResultDto();
                BeanUtils.copyProperties(tbSettleTotal,settleTotalResultDto);
                int settleStatus=tbSettleTotal.getSettleStatus()==null?0:tbSettleTotal.getSettleStatus().intValue();
                settleTotalResultDto.setSettleDate(DateUtil.getDateFormat(tbSettleTotal.getSettleDate()));
                settleTotalResultDto.setSettleStatusName(SettleStatusEnum.getNameByCode(settleStatus));
                settleTotalResultDto.setAuditTime(DateUtil.getDateTimeFormat(tbSettleTotal.getAuditTime()));
                settleTotalResultDto.setCreateTime(DateUtil.getDateTimeFormat(tbSettleTotal.getCreateTime()));
                settleTotalResultDto.setModiTime(DateUtil.getDateTimeFormat(tbSettleTotal.getModiTime()));
                settleTotalResultDtoPage.add(settleTotalResultDto);
            }
        }
        return Result.newSuccess(new PageInfo<>(settleTotalResultDtoPage));
    }
}
